﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using PessModel;
using System.Web.Security;
using PessMvc.Models;
using PessMvc.Helpers;
using System.Data;
using System.IO;
using LinqToExcel;
using LinqToExcel.Domain;
using PessMvc.Lib;
using DoddleReport;
using DoddleReport.Web;
using System.Globalization;
using System.Resources;
using System.Collections;
using System.Reflection;
using DynamicQueryLib;
using LinqKit;

namespace PessMvc.Controllers
{
    [Authorize]
    public class ExpertJudgeController : Controller
    {
        PessModel.PESSEntities db;
        //
        // GET: /ExpertJudge/
        public ExpertJudgeController()
        {
            db = new PessModel.PESSEntities();
        }
        //public ActionResult Index()
        //{
        //    return View();
        //}
        /// <summary>
        /// Find all ExpertGroups, and then put them into a model.
        /// </summary>
        /// <param name="expertGroupID"></param>
        /// <returns></returns>
        private ExpertGroupSelectionModel FillGroupSelectionModel(int expertGroupID)
        {
            int activityID = db.ExpertGroups.Find(expertGroupID).ActivityID;
            var exptGroups = (from eg in db.ExpertGroups
                              where eg.ActivityID == activityID
                              select eg).ToList();
            ExpertGroupSelectionModel exptGroupSelectionModel = new ExpertGroupSelectionModel();
            foreach (var eg in exptGroups)
            {
                exptGroupSelectionModel.ExpertGroups.Add(new ExpertGroupModel() { Id = eg.ID, Name = eg.Callsign, LocalName = eg.Callsign, IsSelected = false, Value = "" });
            }
            return exptGroupSelectionModel;
        }
        public ActionResult Create(int expertGroupID)
        {
            ViewBag.ExpertGroupID = expertGroupID;

            ViewBag.ExpertGroupSelection = FillGroupSelectionModel(expertGroupID);//exptGroupSelectionModel;

            //Generate Expert SerialNumber
            var group=db.ExpertGroups.Find(expertGroupID);
            //expert.SerialNumber = GetExpertSerialNumber(group.SubjectID);
            ExpertJudge expJudge = new ExpertJudge();
            expJudge.SerialNumber = GetExpertSerialNumber(group.ActivityID);

            ViewBag.ExpertGroupCallsign = group.Callsign;
            ViewBag.ActivityID = group.ActivityID;
            ViewBag.Gender = Utility.GenderSelectList(true);
            return View(expJudge);
        }
        public ActionResult CreateExpertJudge()
        {
            ExpertJudgeModel expJudge = new ExpertJudgeModel();
            ViewBag.Gender = Utility.GenderSelectList(true);
            return View(expJudge);
        }
        [HttpPost]
        public ActionResult CreateExpertJudge(ExpertJudgeModel expert)
        {
            if (ModelState.IsValid)
            {
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                string errorMsg = "";

                ExpertJudge expertJudge = ibl.Convert(expert);

                if (ibl.Add(expertJudge,null, out errorMsg) == true)
                {
                    return RedirectToAction("ExpertJudges", "ExpertJudge");
                }
                else
                {
                    ModelState.AddModelError("", errorMsg);
                }
            }

            ViewBag.Gender = Utility.GenderSelectList(expert.Gender);
            return View(expert);
        }
        [HttpPost]
        public ActionResult Create(ExpertJudge expert,List<ExpertGroupModel> expertGroups)
        {
            //expert.Password = "111111";
            if (ModelState.IsValid)
            {
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                string errorMsg="";
                var selectedExpertGroups = (from egm in expertGroups
                                           where egm.IsSelected == true
                                           select new ExpertGroup() {ID=egm.Id }).ToList();
                if (ibl.Add(expert,selectedExpertGroups, out errorMsg) == true)
                {
                    return RedirectToAction("Details", "ExpertGroup", new { id = expert.ExpertGroupID });
                }
                else
                {
                    ModelState.AddModelError("", errorMsg);
                }
            }

            ViewBag.ExpertGroupID = expert.ExpertGroupID;
            var group = db.ExpertGroups.Find(expert.ExpertGroupID);
            ViewBag.ExpertGroupCallsign = group.Callsign;
            ViewBag.ActivityID = group.ActivityID;
            ViewBag.Gender = Utility.GenderSelectList(expert.Gender);
            ViewBag.ExpertGroupSelection = FillGroupSelectionModel(expertGroups.First().Id);//exptGroupSelectionModel;
            return View(expert);
        }

        [HttpPost]
        public ActionResult AddExpertJudges(HttpPostedFileBase file, int activityID)
        {
            // Verify that the user selected a file
            if (file != null && file.ContentLength > 0)
            {
                // extract only the fielname
                var fileName = Path.GetFileName(file.FileName);
                // store the file inside ~/App_Data/uploads folder
                var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                file.SaveAs(path);


                var excel = new ExcelQueryFactory(path);
                //excel.FileName = ;
                excel.DatabaseEngine = DatabaseEngine.Ace;
                excel.AddMapping<ExpertJudgeModel>(m => m.ExpertGroupID, "评委组ID");
                excel.AddMapping<ExpertJudgeModel>(m => m.RealName, "真实姓名");
                excel.AddMapping<ExpertJudgeModel>(m => m.Email, "email地址");
                excel.AddMapping<ExpertJudgeModel>(m => m.Password, "初始密码");
                excel.AddMapping<ExpertJudgeModel>(m => m.Phone, "电话");
                var members = from m in excel.Worksheet<ExpertJudgeModel>()
                              select m;

                string errorMsg = "";
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                foreach (var x in members)
                {
                    if (ibl.IfExpertExists(x.ExpertGroupID, x.RealName) == false&&ibl.IfExpertGroupMatchesActivity(activityID,x.ExpertGroupID))
                    {
                        ExpertJudge expert = new ExpertJudge() { 
                            SerialNumber=CalculateSerialNumber(x.ExpertGroupID),
                            Email = x.Email,
                            ExpertGroupID = x.ExpertGroupID, 
                            RealName = x.RealName, 
                            Phone = x.Phone };
                        //IExpertJudgeBL modified to satisfy many to many relationship between Group and Judge.
                        //Need to be fixed later.
                        if (ibl.Add(expert,db.ExpertGroups.Where(g=>g.ID==expert.ExpertGroupID).ToList(), out errorMsg, x.Password) == false) //Once error is encounted, stop adding remaining experts. Show error message.
                        {
                            throw new Exception(errorMsg);                            
                        }
                    }
                }
            }

            // redirect back to the index action to show the form once again
            return RedirectToAction("Index", new { activityID = activityID });  
        }
        /// <summary>
        /// This is for PESS2
        /// </summary>
        /// <param name="file"></param>
        /// <param name="activityID"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult AddExpertJudges2(HttpPostedFileBase file)
        {
            // Verify that the user selected a file
            if (file != null && file.ContentLength > 0)
            {
                // extract only the fielname
                var fileName = Path.GetFileName(file.FileName);
                // store the file inside ~/App_Data/uploads folder
                var path = Path.Combine(Server.MapPath("~/App_Data/uploads"), fileName);
                file.SaveAs(path);


                var excel = new ExcelQueryFactory(path);
                //excel.FileName = ;
                excel.DatabaseEngine = DatabaseEngine.Ace;
                excel.AddMapping<ExpertJudgeModel>(m => m.SerialNumber, "评委编号");
                excel.AddMapping<ExpertJudgeModel>(m => m.RealName, "真实姓名");
                //excel.AddMapping<ExpertJudgeModel>(m => m.Gender, "性别");
                excel.AddMapping<ExpertJudgeModel>(m => m.Birthdate, "出生年月");
                excel.AddMapping<ExpertJudgeModel>(m => m.Phone, "电话");
                excel.AddMapping<ExpertJudgeModel>(m => m.ContactAddress, "通讯地址");
                excel.AddMapping<ExpertJudgeModel>(m => m.ZipCode, "邮政编码");
                excel.AddMapping<ExpertJudgeModel>(m => m.Password, "初始密码");
                var members = from m in excel.Worksheet<ExpertJudgeModel>()
                              select m;

                string errorMsg = "";
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                foreach (var x in members)
                {
                    if (ibl.IfExpertExists2(x) == false)
                    {
                        ExpertJudge expert = ibl.Convert(x);
                        //IExpertJudgeBL modified to satisfy many to many relationship between Group and Judge.
                        //Need to be fixed later.
                        if (ibl.Add(expert, null, out errorMsg, x.Password) == false) //Once error is encounted, stop adding remaining experts. Show error message.
                        {
                            ModelState.AddModelError("",string.Format("{0}:{1},{2}",errorMsg,expert.SerialNumber,expert.RealName));
                            break;
                            //throw new Exception(errorMsg);
                        }
                    }
                }
            }

            // redirect back to the index action to show the form once again
            string messages = string.Join("; ", ModelState.Values
                                        .SelectMany(x => x.Errors)
                                        .Select(x => x.ErrorMessage));
            return RedirectToAction("ExpertJudges", "ExpertJudge", new {ErrorMessage=messages });
        }
        private string CalculateSerialNumber(int? expertGroupID)
        {
            return GetExpertSerialNumber(db.ExpertGroups.Find(expertGroupID).ActivityID);
        }
        //private string GetExpertSerialNumber(int? subjectID)
        //{
        //    int activityID = db.Subjects.Find(subjectID).ActivityID;

        //    int expertCount = (from e in db.ExpertJudges
        //                       where e.ExpertGroup.Subject.ID == subjectID && e.ExpertGroup.Subject.ActivityID == activityID
        //                       select e).Count();

        //    return string.Format("A{0}S{1}PW{2}", activityID, subjectID, expertCount);

        //}
        private string GetExpertSerialNumber(int? activityID)
        {
            throw new Exception("This function definition is commented out because FK between Expertgroup and Subject has been removed.");
            //List<string> snlist=(from e in db.ExpertJudges 
            //                join g in db.ExpertGroups on e.ExpertGroupID equals g.ID
            //                join s in db.Subjects on g.SubjectID equals s.ID
            //                where s.ActivityID==activityID                            
            //                select e.SerialNumber).ToList();
            //int expertCount=snlist.Count==0?0:snlist.Max(t=>Convert.ToInt32(t));//.GroupBy(e=>e.SerialNumber).Count();
            //decimal ab=Convert.ToDecimal(expertCount) / 1000;
            //int a = (int)ab;
            //int b = (int)((ab - a) * 1000);

            //return string.Format("{0}{1}", activityID, Utility.FormatExpertCount(++b));

        }
        public ActionResult Index(int activityID,int? expertGroupID)
        {
            var experts = db.ExpertJudges.Where(e => (from eg in e.ExpertGroups where eg.ActivityID==activityID select eg).Count()>0);
            if (expertGroupID != null)
            {
                var expertGroup = db.ExpertGroups.Find(expertGroupID);
                experts = expertGroup.ExpertJudges.Where(e=>true).AsQueryable();
                          //experts.Where(e => e.ExpertGroupID == expertGroupID);
            }

            var expertModels = experts.ToList().ToExpertJudgeModelList(activityID);

            ViewBag.ActivityID = activityID;
            ViewBag.ExpertGroupID=new SelectList(db.ExpertGroups.Where(g=>g.ActivityID==activityID),"ID","Callsign");
            return View(expertModels);
        }
        public ActionResult ExpertJudges(string keyword="",string errorMessage="")
        {
            List<ExpertJudge> model;
            //IQueryable<ExpertJudgeModel>
            var query = db.ExpertJudges;//.ToList().ToExpertJudgeModelList();//.AsQueryable();
            if (keyword.Trim() != "")
            {
                model = this.Search<ExpertJudge>(keyword, query).ToList();
            }
            else
            {
                model = query.ToList();
            }
            ViewBag.ErrorMessage = errorMessage;
            return View(model.ToExpertJudgeModelList());
        }


        public ActionResult ChooseExperts(int expertGroupID)
        {
            ViewBag.ExpertGroupID = expertGroupID;
            ViewBag.ActivityID = db.ExpertGroups.Find(expertGroupID).ActivityID;
            var allexperts = db.ExpertJudges;
            var choosedExps = db.ExpertGroups.Find(expertGroupID).ExpertJudges.Select(c => c.SerialNumber);
            var available = (from a in allexperts
                             where choosedExps.Contains(a.SerialNumber) == false
                             select a).ToList();

            return View(available.ToExpertJudgeModelList());
        }
        [HttpPost, ActionName("ChooseExperts")]
        public ActionResult ChooseExpertsConfirmed(int expertGroupID)
        {
            string[] selectedExpertSNList = Request["ExpertSN"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            ExpertGroup group = db.ExpertGroups.Find(expertGroupID);
            if (group != null)//verify that group exists.
            {
                foreach (string sn in selectedExpertSNList)
                {
                    if (group.ExpertJudges.Where(e => e.SerialNumber.Trim() == sn.Trim()).Count() == 0)//verify that the group does not already contain the expert.
                    {
                        ExpertJudge expert = db.ExpertJudges.Find(sn);
                        group.ExpertJudges.Add(expert);
                    }
                    db.SaveChanges();
                }
            }
            return RedirectToAction("Details", "ExpertGroup", new { id = expertGroupID });
        }

        [HttpPost]
        public ActionResult ResetPassword(string password)
        {
            if (password.Trim().Length >= 3)
            {
                string[] selectedExpertSNList = Request["ExpertSN"].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                foreach (string sn in selectedExpertSNList)
                {
                    //ExpertJudge expert = db.ExpertJudges.Find(sn);
                    var user = Membership.GetUser(sn);
                    user.UnlockUser();
                    string oldpsw = user.ResetPassword();
                    user.ChangePassword(oldpsw, password);
                }
                return RedirectToAction("ExpertJudges", "ExpertJudge");
            }
            else
            {
                return RedirectToAction("ExpertJudges", "ExpertJudge", new { errorMessage = "密码不能小于3个字符！" });
            }
        }
        /// <summary>
        /// This function removes expert from a group or from an activity, if activityID is supplied.
        /// </summary>
        /// <param name="SerialNumber"></param>
        /// <param name="expertGroupID"></param>
        /// <param name="returnUrl"></param>
        /// <returns></returns>
        public ActionResult Dismiss(string SerialNumber, int expertGroupID, string returnUrl,int? activityID=null)
        {
            if (activityID != null)
            {
                Activity activity = db.Activities.Find(activityID);
                foreach (var g in activity.ExpertGroups)
                {                    
                    ExpertJudge expert = db.ExpertJudges.Find(SerialNumber);
                    g.ExpertJudges.Remove(expert);
                    db.SaveChanges();
                }
            }
            else
            {
                ExpertGroup expgroup = db.ExpertGroups.Find(expertGroupID);
                if (expgroup != null && expgroup.ExpertJudges.Select(e => e.SerialNumber).Contains(SerialNumber))
                {
                    ExpertJudge expert = db.ExpertJudges.Find(SerialNumber);
                    expgroup.ExpertJudges.Remove(expert);
                    db.SaveChanges();
                }
            }
            return Go2ReturnUrl(returnUrl);
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="userName">SerialNumber</param>
        /// <returns></returns>
        [Authorize(Roles="Admin,ExpertJudge")]
        public ActionResult Edit(string serialNumber,string returnUrl,int activityID)
        {
            if (Utility.IsCurrentUserExpertHimself(serialNumber)||Roles.IsUserInRole("Admin"))
            {
                var expert = db.ExpertJudges.Find(serialNumber); expert.Email = Membership.GetUser(serialNumber).Email;
                ViewBag.Gender = Utility.GenderSelectList(expert.Gender);
                ViewBag.ReturnUrl = returnUrl;
                //Available expert groups under an activity.
                ExpertGroupSelectionModel selectionModel = FillGroupSelectionModel(expert.ExpertGroups.Where(e => e.ActivityID == activityID).FirstOrDefault().ID);//
                foreach (var g in selectionModel.ExpertGroups)
                {
                    if (expert.ExpertGroups.Select(eg => eg.ID).Contains(g.Id))
                    {
                        g.IsSelected = true;
                    }
                }
                ViewBag.ExpertGroupSelection = selectionModel;
                ViewBag.HideArchiveDetails = expert.ExpertGroups.FirstOrDefault().Activity.HideArchiveDetails;
                return View(expert);
            }
            else
            {
                throw new Exception("Not authorized.");
            }
        }
        [HttpPost]
        public ActionResult Edit(ExpertJudge expertJudge, string returnUrl, List<ExpertGroupModel> expertGroups)
        {
            if (ModelState.IsValid)
            {
                //var expert=db.ExpertJudges.Find(expertJudge.SerialNumber);
                db.Entry(expertJudge).State = EntityState.Modified;
                //System.Diagnostics.Debug.WriteLine(expertJudge.ExpertGroups.Count);
                db.SaveChanges();
                db.Dispose();               
                
                //var seletedGroups = expertGroups.Where(eg => eg.IsSelected == true);
                //foreach (var g in seletedGroups)
                //{
                //    ExpertGroup group = db.ExpertGroups.Find(g.Id);
                //    if (!group.ExpertJudges.Contains(expertJudge))
                //    {
                //        group.ExpertJudges.Add(expertJudge);
                //    }
                //}
                //db.SaveChanges();

                var user = Membership.GetUser(expertJudge.SerialNumber);
                user.Email = expertJudge.Email;
                Membership.UpdateUser(user);

                db = new PESSEntities();
                expertJudge = db.ExpertJudges.Find(expertJudge.SerialNumber);
                //var seletedGroups = expertGroups.Where(eg => eg.IsSelected == true);
                if (expertGroups != null)
                {
                    foreach (var g in expertGroups)
                    {
                        ExpertGroup group = db.ExpertGroups.Where(eg => eg.ID == g.Id).FirstOrDefault();
                        if (g.IsSelected && !group.ExpertJudges.Contains(expertJudge))
                        {
                            //!group.ExpertJudges.Contains(expertJudge)
                            group.ExpertJudges.Add(expertJudge);
                        }
                        else if (g.IsSelected == false && group.ExpertJudges.Contains(expertJudge))
                        {
                            group.ExpertJudges.Remove(expertJudge);
                        }
                    }
                    db.SaveChanges();
                }

                return Go2ReturnUrl(returnUrl);//Redirect(returnUrl);
            }
            else
            {
                ViewBag.Gender = Utility.GenderSelectList(expertJudge.Gender);
                return View(expertJudge);
            }

        }
        [Authorize(Roles="Admin,ExpertJudge")]
        public ActionResult EditExpertJudge(string serialNumber)
        {
            //if ( Roles.IsUserInRole("Admin"))
            //{
                var expert = db.ExpertJudges.Find(serialNumber);
                if (Roles.IsUserInRole("Admin") || Utility.IsCurrentUserExpertHimself(serialNumber))
            {
                expert.Email = Membership.GetUser(serialNumber).Email;
                ViewBag.Gender = Utility.GenderSelectList(expert.Gender);
                IExpertJudgeBL ibl = new ExpertJudgeBL();
                //ViewBag.ReturnUrl = returnUrl;
                //Available expert groups under an activity.
                return View(ibl.Convert(expert));
            }
            else
            {
                throw new Exception("Not authorized.");
            }
        }
        [HttpPost]
        public ActionResult EditExpertJudge(ExpertJudgeModel model,string returnUrl="")
        {
            if (ModelState.IsValid)
            {
                //var expert=db.ExpertJudges.Find(model.SerialNumber);
                ExpertJudgeBL ibl=new ExpertJudgeBL();
                ExpertJudge expert = ibl.Convert(model);
                db.Entry(expert).State = EntityState.Modified;
                db.SaveChanges();
                db.Dispose();
                if (Roles.IsUserInRole("Admin"))
                {
                    return RedirectToAction("ExpertJudges", "ExpertJudge");
                }
                else
                {
                    return Go2ReturnUrl(returnUrl);
                }
            }
            else
            {
                ViewBag.Gender = Utility.GenderSelectList(model.Gender);
                return View(model);
            }
        }
        public ActionResult Go2ReturnUrl(string returnUrl)
        {
            if (Url.IsLocalUrl(returnUrl) && returnUrl.Length > 1 && returnUrl.StartsWith("/")
                        && !returnUrl.StartsWith("//") && !returnUrl.StartsWith("/\\"))
            {
                return Redirect(returnUrl);
            }
            else
            {
                //return RedirectToAction("Index", "Activity");
                //For the sake of fewer clicks. We let expert judges see archives after log on.
                //int activityID=db.ExpertJudges.Find(User.Identity.Name).ExpertGroups.FirstOrDefault().ActivityID;
                //HttpContext.Session.Add("ActivityID", activityID);
                //return RedirectToAction("Index", "Archive", new  {ActivityID=activityID});
                return RedirectToAction("Index", "Activity");
            }
        }

        public ActionResult Delete(string serialNumber, string returnUrl)
        {
            ExpertJudge expert = db.ExpertJudges.Find(serialNumber);
            ViewBag.ReturnUrl = returnUrl;
            if (expert == null)
            {
                return HttpNotFound();
            }
            return View(expert);
        }

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(string serialNumber, string returnUrl)
        {
            ExpertJudge expert = db.ExpertJudges.Find(serialNumber);
            ViewBag.ReturnUrl = returnUrl;
            //int expertGroupID=(int)expert.ExpertGroupID;
            if (expert.Scores.Count!=0)
            {
                ModelState.AddModelError("", "该评委已经评分，不能删除！");
            }
            else if (expert.ExpertComments.Count != 0)
            {
                ModelState.AddModelError("", "该评委已经输入评语，不能删除！");
            }
            else if (Membership.GetUser(serialNumber)!=null&&!Membership.DeleteUser(serialNumber))
            {
                ModelState.AddModelError("", "该用户无法删除！请联系系统管理员。");
            }
            else
            {
                //foreach (var group in expert.ExpertGroups)
                //{
                //    group.ExpertJudges.Remove(expert);
                //}
                expert.ExpertGroups.ForEach(g=>g.ExpertJudges.Remove(expert));
                expert.ContractAssignments.ForEach(c => c.Contract.ContractAssignments.Remove(c));
                db.ExpertJudges.Remove(expert);
                db.SaveChanges();
                //return RedirectToAction("Details", "ExpertGroup", new {id=expertGroupID });
                return Go2ReturnUrl(returnUrl);
            }            
                
            return View(expert);            
        }

        /// <summary>
        /// This is for PESS2.
        /// </summary>
        /// <param name="keyword"></param>
        /// <returns></returns>
        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult ExportToExcel2(string keyword="")
        {
            List<ExpertJudge> result;
            //IQueryable<ExpertJudgeModel>
            var query = db.ExpertJudges;//.ToList().ToExpertJudgeModelList();//.AsQueryable();
            if (keyword.Trim() != "")
            {
                result = this.Search<ExpertJudge>(keyword, query).ToList();
            }
            else
            {
                result = query.ToList();
            }
                        
            //IQueryable<ExpertJudgeModel> query1 = from m in db.ExpertJudges.ToList().ToExpertJudgeModelList().AsQueryable()
            //                                     select m;
            //var query =keyword==""?db.ExpertJudges.ToList().ToExpertJudgeModelList():Search<ExpertJudgeModel>(keyword,query1).ToList();//db.GetExpertJudges(activityID);//db.ExpertJudges.Where(e => e.ExpertGroup.Subject.ActivityID == activityID);
            //var expertModels = experts.ToList().ToExpertJudgeModelList();
            //string subTitle = string.Format("{0}:{1}", subject != null ? subject.Name : "", activity.Name);
            var report = new DoddleReport.Report(result.ToExpertJudgeModelList().ToReportSource());
            for (int i = 0; i < report.DataFields.Count; i++)
            {
                report.DataFields[i].HeaderText = Utility.Translate<PessResources.ExpertJudge>(report.DataFields[i].Name);
            }
            IReportWriter writer = new DoddleReport.Writers.ExcelReportWriter();
            return new ReportResult(report, writer, "application/vnd.ms-excel") { FileName = HttpUtility.UrlPathEncode("评委名单.xls") };
        }

        [Authorize(Roles = "Admin")]
        [HttpPost]
        public ActionResult ExportToExcel(int activityID)
        {
            //var query = db.GetArchiveList(activityID).AsEnumerable();//db.Archives.Where(a => a.Subject.ActivityID == activityID);

            //return CreateReport(query,new DoddleReport.Writers.ExcelReportWriter(), selectedProperties);
            var query = db.GetExpertJudges(activityID);//db.ExpertJudges.Where(e => e.ExpertGroup.Subject.ActivityID == activityID);
            //var expertModels = experts.ToList().ToExpertJudgeModelList();
            //string subTitle = string.Format("{0}:{1}", subject != null ? subject.Name : "", activity.Name);
            var report = new DoddleReport.Report(query.ToReportSource());
            for (int i = 0; i < report.DataFields.Count; i++)
            {
                report.DataFields[i].HeaderText = Utility.Translate<PessResources.ExpertJudge>(report.DataFields[i].Name);
            }
            IReportWriter writer = new DoddleReport.Writers.ExcelReportWriter();
            return new ReportResult(report, writer, "application/vnd.ms-excel") { FileName = HttpUtility.UrlPathEncode("评委名单.xls") };
        }
        /// <summary>
        /// Expert an excel report showing (成果编码、名称、总分、是否通过).
        /// No paprameter is required. Because system can figure out expert's sn
        /// </summary>
        /// <returns></returns>
        //[Authorize(Roles = "ExpertJudge")]
        //public ActionResult ExportGradingReport()
        //{
        //    var query=
        //}

        private List<PropertyInfo> GetExpertProperties<T>()
        {
            var properties = typeof(T).GetProperties(BindingFlags.DeclaredOnly
                                                           | BindingFlags.Public
                                                           | BindingFlags.Instance)
                                                           .Where(p => p.PropertyType == typeof(string)&&p.Name != "Email" ).ToList();
            return properties;
        }
        private IQueryable<T> Search<T>(string keyword,IQueryable<T> query)
        {
            keyword = keyword.Trim();
            //Get string type properties from Archive
            var properties = GetExpertProperties<T>();

            //Prepare the filters
            List<DynamicQueryLib.Filter> filterList = new List<DynamicQueryLib.Filter>();
            for (int i = 0; i < properties.Count; i++)// var prop in properties)
            {
                DynamicQueryLib.Filter f = new DynamicQueryLib.Filter();
                if (i == 0)
                {
                    f.Connector = FilterConnectorType.AND;//the first connector must be AND, otherwise, you get a true
                }
                else
                {
                    f.Connector = FilterConnectorType.OR;
                }
                f.PropertyName = properties[i].Name;
                f.PropertyType = typeof(string);
                f.Values.Add(keyword);
                f.Operator = RelationalOperators.Contains;
                filterList.Add(f);
            }
            var predicate = LambdaExpressionHelper<T>.CreatePredicate<T>(filterList);
            var result = query.AsExpandable<T>();
            result = result.Where(predicate);

            return result;
        }

    }
}
